package com.yunqi.autovender.activity;

import android.animation.ValueAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.databinding.DataBindingUtil;
import android.graphics.Bitmap;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;

import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import com.alibaba.android.arouter.launcher.ARouter;
import com.google.gson.Gson;
import com.kongqw.serialportlibrary.SerialPortManager;
import com.kongqw.serialportlibrary.listener.OnOpenSerialPortListener;
import com.kongqw.serialportlibrary.listener.OnSerialPortDataListener;
import com.yunqi.autovender.R;
import com.yunqi.autovender.adapter.MenuAdapter;
import com.yunqi.autovender.adapter.HProductAdapter;

import cn.jpush.android.api.JPushInterface;
import google.architecture.common.util.StringUtils;
import google.architecture.common.util.TimeUtil;
import google.architecture.common.widget.xrecyclerview.XRecyclerView;
import google.architecture.coremodel.callback.ConfirmCallback;
import google.architecture.coremodel.callback.MainClickCallback;
import google.architecture.coremodel.callback.ProductItemClickCallback;

import com.yunqi.autovender.adapter.PullMenuAdapter;
import com.yunqi.autovender.adapter.SubMenuAdapter;
import com.yunqi.autovender.adapter.VProductAdapter;
import com.yunqi.autovender.databinding.ActivityMainBinding;
import com.yunqi.autovender.listener.OnClassifyListener;
import com.yunqi.autovender.manager.ClassifyWrapper;
import com.yunqi.autovender.manager.RecyclerViewWrapper;
import com.yunqi.autovender.model.CargoInfo;
import com.yunqi.autovender.model.DrugInfo;
import com.yunqi.autovender.model.GlobalData;
import com.yunqi.autovender.model.PushInfo;
import com.yunqi.autovender.service.ObserverService;
import com.yunqi.autovender.view.ConfirmDialog;
import com.yunqi.autovender.view.LoadingDialog;
import com.yunqi.autovender.view.LockDialog;
import com.yunqi.autovender.view.PageGridView;
import com.yunqi.autovender.view.PayFailedDialog;
import com.yunqi.autovender.view.PaySuccessDialog;
import com.yunqi.autovender.view.PaymentDialog;
import com.yunqi.autovender.view.SelectPayTypeDialog;
import com.yunqi.autovender.view.SetupDialog;
import com.yunqi.usbprinter.USBPrinterMgr;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import google.architecture.common.base.BaseActivity;
import google.architecture.common.util.ToastUtils;
import google.architecture.coremodel.constant.ARGConstant;
import google.architecture.coremodel.constant.ARouterPath;
import google.architecture.coremodel.constant.ErrorCode;
import google.architecture.coremodel.constant.EventCode;
import google.architecture.coremodel.datamodel.http.entities.ClassifyData;
import google.architecture.coremodel.datamodel.http.entities.ProductData;
import google.architecture.coremodel.datamodel.http.entities.ShoppingCarItem;
import google.architecture.coremodel.datamodel.http.entities.TerInfoData;
import google.architecture.coremodel.helper.AppConfigHelper;
import google.architecture.coremodel.navigator.ProductNavigator;
import google.architecture.coremodel.rx.RxEvent;
import google.architecture.coremodel.util.DoubleMathUtil;
import google.architecture.coremodel.viewmodel.ProductViewModel;

/**
 * 主界面
 */
public class MainActivity extends BaseActivity implements ProductNavigator, OnOpenSerialPortListener {
    private static final int TODO_JUMP_SETTINGS = 1;//解锁后跳转到SettingsActivity
    private static final int TODO_ONLY_UNLOCK = 0;//仅仅解锁后，LockDialog消失
    private ActivityMainBinding activityMainBinding;
    private RecyclerView.Adapter mProductAdapter;
    private ProductViewModel productViewModel;
    private MenuAdapter mMenuAdapter;
    private PullMenuAdapter mPullMenuAdapter;
    private List<ClassifyData.Classify> mSubClassifyList=new ArrayList<>();
    private SubMenuAdapter mSubMenuAdapter;
    private ClassifyData classifyData;
    private List<ProductData.Product> mProductList = new ArrayList<>();
    private String mTerNo;
    private TextWatcher mTextWatcher;
    private PaymentDialog mPaymentDialog;
    private ConfirmDialog mConfirmDialog;
    private SerialPortManager mSerialPortManager;
    private LoadingDialog mLoadingDialog;
    private LoadingDialog mOutStackDialog;//出货等待对话框
    private AppConfigHelper mAppConfigHelper;
    private LockDialog mLockDialog;
    private String mTradeNo;
    private int mMaxPrintLength = 12;
    private PushInfo mPushInfo;
    private RecyclerViewWrapper mRecyclerViewWrapper;
    private ClassifyWrapper mClassifyWrapper;
    private boolean mMenuIsShow = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ARouter.getInstance().inject(MainActivity.this);
        activityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        activityMainBinding.setCallback(mMainClickCallback);
        initReceiver();
        initData();
    }


    @Override
    public void onBackPressed() {
    }

    private void initData() {
        initRxBus();
        initConfig();
        initClassify();
        initRecyclerView();
        initSearchListener();
        initSerialPort();
        initUSBPrint();
        productViewModel.getTerNo();
    }

    private void initUSBPrint(){
        USBPrinterMgr.getInstance().init(this);
    }



    private void initConfig(){
        mAppConfigHelper = new AppConfigHelper(this);
        try {
            mMaxPrintLength = Integer.parseInt(mAppConfigHelper.getMaxPrintLength());
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        try {
            mCountDown = Integer.parseInt(mAppConfigHelper.getCountDownTime());
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        productViewModel = new ProductViewModel(this.getApplication());
        productViewModel.setProductNavigator(this);
        mLoadingDialog = new LoadingDialog(this);
    }

    private void initReceiver() {
        IntentFilter timeFilter = new IntentFilter();
        timeFilter.addAction("android.net.ethernet.ETHERNET_STATE_CHANGED");
        timeFilter.addAction("android.net.ethernet.STATE_CHANGE");
        timeFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        timeFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
        timeFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
        registerReceiver(mNetReceiver, timeFilter);
    }

    private void initSerialPort() {
        mSerialPortManager = new SerialPortManager();
        String strTimeOut = mAppConfigHelper.getTimeOut();
        try {
            long timeOut = Long.parseLong(strTimeOut) * 1000;
            mSerialPortManager.setTimeOut(timeOut);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        mSerialPortManager.setOnOpenSerialPortListener(this)
                .setOnSerialPortDataListener(new OnSerialPortDataListener() {
                    @Override
                    public void onDataReceived(byte[] bytes) {
                        Log.i(TAG, "onDataReceived [ byte[] ]: " + Arrays.toString(bytes));
                        String command = StringUtils.toHexString(bytes);
                        doWithReceivedCommand(command);
                    }


                    @Override
                    public void onDataSent(byte[] bytes) {
                        Log.i(TAG, "onDataSent [ byte[] ]: " + Arrays.toString(bytes));
                        String command = StringUtils.toHexString(bytes);
                        Log.i(TAG, "command: " + command);

                    }

                    @Override
                    public void onConnFailed() {
                        ToastUtils.showShortToast(getString(R.string.disconnect_serail_port));
                        productViewModel.saveMistake(getTerNo(),ErrorCode.NO_COMMAND_ERROR);
                    }

                    @Override
                    public void onConnTimeOut() {
                        productViewModel.saveMistake(getTerNo(),ErrorCode.NO_COMMAND_ERROR);
                        //退款
                        productViewModel.tradeRefund(mTradeNo);
                        hideOutStackDialog();
                        showOutStackFailedDialog();
                    }
                });
        //如果是第一次启动，必须先设置配置信息
        if (mAppConfigHelper.isFirstLauncher()) {
            showSetupDialog();
        } else {
            connectSerialPort();
        }
    }


    private void connectSerialPort() {
        if (openSerialPort()) {
            Log.i(TAG, "Open serial port success!");
        } else {
            showSetupDialog();
        }
    }


    private void showSetupDialog() {
        SetupDialog dialog = new SetupDialog(this, 1) {
            @Override
            public void onConfigComplied() {
                connectSerialPort();
            }
        };
        dialog.show();
    }

    private void initSearchListener() {
        mTextWatcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (mClassifyWrapper.getType() == ClassifyWrapper.TYPE_EXPANDABLELISTVIEW) {
                    if (mMenuAdapter == null) {
                        return;
                    }
                    int groupPosition = mMenuAdapter.getGroupPosition();
                    mClassifyWrapper.collapseGroup(groupPosition);
                    mMenuAdapter.setGroupAndChildPosition(0, -1);
                } else {
                    if (mPullMenuAdapter == null) {
                        return;
                    }
                    mPullMenuAdapter.setGroupPosition(0);
                    activityMainBinding.setSelectMenu("全部");
                    mSubClassifyList.clear();
                    mSubMenuAdapter.notifyDataSetChanged();
                }
                productViewModel.setTypeId(-1);
                String words = activityMainBinding.editSearch.getText().toString();
                productViewModel.searchDrug(words, getTerNo());
            }
        };
        activityMainBinding.editSearch.addTextChangedListener(mTextWatcher);
    }


    private void initClassify() {
        final View listviewNavi = activityMainBinding.listviewNavi;
        mClassifyWrapper = new ClassifyWrapper(this, listviewNavi);
        mClassifyWrapper.setOnClassifyListener(mOnClassifyListener);
        mClassifyWrapper.initClassify();
        if (mClassifyWrapper.getType() == ClassifyWrapper.TYPE_RECYCLERVIEW) {
            activityMainBinding.recyclerSubMenu.setLayoutManager(new GridLayoutManager(this, 3));
            mSubMenuAdapter=new SubMenuAdapter(this,mSubClassifyList);
            mSubMenuAdapter.setOnClassifyListener(mOnClassifyListener);
            activityMainBinding.recyclerSubMenu.setAdapter(mSubMenuAdapter);
        }
    }


    private void initRecyclerView() {
        mRecyclerViewWrapper = new RecyclerViewWrapper(this, activityMainBinding.recyclerViewContent);
        View recyclerView = activityMainBinding.recyclerViewContent;
        //兼容横竖屏
        if (recyclerView instanceof XRecyclerView) {
            mProductAdapter = new VProductAdapter(productItemClickCallback, mProductList);
            mRecyclerViewWrapper.initRefreshView(recyclerView);
        } else if (recyclerView instanceof PageGridView) {
            mProductAdapter = new HProductAdapter(productItemClickCallback, mProductList);
            mRecyclerViewWrapper.initRefreshView(activityMainBinding.refreshLayout);
        }
        mRecyclerViewWrapper.setRefreshListener(new RecyclerViewWrapper.RefreshListener() {
            @Override
            public void onRefresh() {
                productViewModel.setPage(1);
                String terNo = getTerNo();
                if (TextUtils.isEmpty(terNo)) {
                    productViewModel.getTerNo(false);
                } else {
                    productViewModel.loadData(terNo);
                }
            }

            @Override
            public void onLoadMore() {
                int page = productViewModel.getPage();
                page++;
                productViewModel.setPage(page);
                productViewModel.loadData(getTerNo());
            }
        });
        mRecyclerViewWrapper.setAdapter(mProductAdapter);
    }

    private String getTerNo() {
        if (TextUtils.isEmpty(mTerNo)) {
            mTerNo = (String) GlobalData.getInstance().getData(ARGConstant.ARG_TERNO);
        }
        return mTerNo;
    }

    ProductItemClickCallback productItemClickCallback = new ProductItemClickCallback() {
        @Override
        public void onClick(ProductData.Product product, int action) {
            switch (action) {
                case ACTION_ITEM_CLICK:
                    ARouter.getInstance()
                            .build(ARouterPath.ProductDetailAct)
                            .withParcelable("product", product)
                            .withTransition(R.anim.activity_up_in, R.anim.activity_up_out)
                            .navigation(MainActivity.this);
                    break;
                case ACTION_BUY_CLICK:
                    SelectPayTypeDialog selectPayTypeDialog = new SelectPayTypeDialog(MainActivity.this, new SelectPayTypeDialog.PayTypeCallback() {
                        @Override
                        public void onSelectPayType(int payType) {
                            String terNo = (String) GlobalData.getInstance().getData(ARGConstant.ARG_TERNO);
                            List<DrugInfo> dugInfoList = new ArrayList<>();
                            DrugInfo info = new DrugInfo();
                            info.setDrugName(product.getTitle());
                            info.setPlanId(product.getPlanId());
                            info.setDrugPrice(product.getPrice());
                            info.setQuantity(1);
                            dugInfoList.add(info);
                            String drugInfos = new Gson().toJson(dugInfoList);
                            double totalPrice = product.getPrice();
                            productViewModel.creatTrade(terNo, payType, drugInfos);
                            mPaymentDialog = new PaymentDialog(MainActivity.this, totalPrice);
                            mPaymentDialog.show();
                        }
                    });
                    selectPayTypeDialog.show();
                    break;
                case ACTION_SHOPPING_CAR_CLICK:
                    mConfirmDialog = new ConfirmDialog(MainActivity.this, new ConfirmCallback() {
                        @Override
                        public void onClick(int action) {
                            mConfirmDialog.dismiss();
                            if (action == ACTION_CONFIRM) {
                                productViewModel.add2ShoppingCar(product);
                            }
                        }
                    });
                    mConfirmDialog.show();
            }
        }
    };
    private MainClickCallback mMainClickCallback = new MainClickCallback() {

        @Override
        public void onClick(int action) {
            switch (action) {
                case ACTION_SEARCH_CLICK:
                    ARouter.getInstance()
                            .build(ARouterPath.SearchAct)
                            .withTransition(R.anim.activity_up_in, R.anim.activity_up_out)
                            .navigation(MainActivity.this);
                    break;
                case ACTION_SHOPPING_CAR_CLICK:
                    ARouter.getInstance()
                            .build(ARouterPath.ShoppingCarAct)
                            .withTransition(R.anim.activity_up_in, R.anim.activity_up_out)
                            .navigation(MainActivity.this);
                    break;
                case ACTION_SETTINGS_CLICK:
                    mLockDialog = new LockDialog(MainActivity.this, LockDialog.STATUS_UNLOCKING) {
                        @Override
                        public void onUnlocked(String pwd) {
                            productViewModel.verficatePwd(getTerNo(), pwd, TODO_JUMP_SETTINGS);

                        }
                    };
                    mLockDialog.show();
                    break;
                case ACTION_PULL_MENU:
                    if (mMenuIsShow) {
                        closePullMenu();
                    } else {
                        openPullMenu();
                    }
                    break;
                case ACTION_PULL_MENU_BG:
                    closePullMenu();
                    break;

            }
        }
    };

    @Override
    protected void onDestroy() {
        if (null != mSerialPortManager) {
            mSerialPortManager.closeSerialPort();
            mSerialPortManager = null;
        }
        if (mNetReceiver != null)
            unregisterReceiver(mNetReceiver);
        if (mTextWatcher != null)
            activityMainBinding.editSearch.removeTextChangedListener(mTextWatcher);
        productViewModel.setProductNavigator(null);
        unSubscribeRxBus();
        USBPrinterMgr.getInstance().destory();
        super.onDestroy();

    }

    @Override
    public void showClassify(ClassifyData classifyData) {
        this.classifyData = classifyData;
        if (classifyData != null) {
            List<ClassifyData.Classify> data = classifyData.getData();
            if (data != null && !data.isEmpty()) {
                productViewModel.setTypeId(data.get(0).getId());
                activityMainBinding.setSelectMenu(data.get(0).getTypeName());
                if (mClassifyWrapper.getType() == ClassifyWrapper.TYPE_EXPANDABLELISTVIEW) {
                    mMenuAdapter = new MenuAdapter(this, this.classifyData);
                    mClassifyWrapper.setAdapter(mMenuAdapter);
                } else if (mClassifyWrapper.getType() == ClassifyWrapper.TYPE_RECYCLERVIEW) {
                    mPullMenuAdapter = new PullMenuAdapter(this, data);
                    mPullMenuAdapter.setOnClassifyListener(mOnClassifyListener);
                    mClassifyWrapper.setAdapter(mPullMenuAdapter);
                }
            }
        }
    }

    @Override
    public void showContent(List<ProductData.Product> list, int page) {
        mRecyclerViewWrapper.onRefreshComplete();
        if (page == 1) {
            mProductList.clear();
            mProductList.addAll(list);
            mProductAdapter.notifyDataSetChanged();
        } else {
            mProductList.addAll(list);
            mProductAdapter.notifyDataSetChanged();
        }
        //当数量小于每页的数目时，表示没有下一页了
        int size = list.size();
        if (size < ProductViewModel.SIZE) {
            mRecyclerViewWrapper.setLoadingMoreEnabled(false);
        } else {
            mRecyclerViewWrapper.setLoadingMoreEnabled(true);
        }
    }

    @Override
    public void showError(int code, String errorMsg) {
        ToastUtils.showShortToast(errorMsg);
        switch (code) {
            case ErrorCode.FAILED_GET_TERNO:
            case ErrorCode.FAILED_GET_PRODUCT:
                mRecyclerViewWrapper.onRefreshComplete();
                break;
            case ErrorCode.FAILED_CREATE_ORDER:
            case ErrorCode.FAILED_CREATE_QRCODE:
                mPaymentDialog.hideLoading();
                break;
        }
    }

    @Override
    public void showLoading() {
        if (mLoadingDialog != null && !mLoadingDialog.isShowing()) {
            mLoadingDialog.show();
        }
    }

    @Override
    public void hideLoading() {
        if (mLoadingDialog != null && mLoadingDialog.isShowing()) {
            mLoadingDialog.dismiss();
        }
    }


    private void hideOutStackDialog() {
        if (mOutStackDialog != null && mOutStackDialog.isShowing()) {
            mOutStackDialog.dismiss();
        }
    }

    @Override
    public void onReturnTerInfo(TerInfoData.Data data) {
        GlobalData.getInstance().putData(ARGConstant.ARG_TERNO, data.getTerNo());
        GlobalData.getInstance().putData(ARGConstant.ARG_PHONE, data.getDealerPhone());
        GlobalData.getInstance().putData(ARGConstant.ARG_CARGO_INFO, new CargoInfo(data.getMaxUnit(), data.getMaxLine(), data.getMaxColumn()));
        mAppConfigHelper.saveTimeOut(20);
        mAppConfigHelper.saveCountDownTime(data.getOperateTime());
        mAppConfigHelper.saveMaxPrintLength(data.getPrintMaxNum());
        activityMainBinding.setTerNo(data.getTerNo());
        activityMainBinding.setPhone(data.getDealerPhone());
        JPushInterface.setAliasAndTags(getApplicationContext(),
                data.getTerNo(),
                null,
                null);
    }

    /**
     * 解锁成功回调
     */
    @Override
    public void onUnlocked(int todo) {
        if (mLockDialog != null && mLockDialog.isShowing()) {
            mLockDialog.dismiss();
        }
        switch (todo) {
            case TODO_JUMP_SETTINGS:
                ARouter.getInstance()
                        .build(ARouterPath.SettingsAct)
                        .withTransition(R.anim.activity_up_in, R.anim.activity_up_out)
                        .navigation(MainActivity.this);
                break;
            case TODO_ONLY_UNLOCK:
                break;
        }

    }

    @Override
    public void showUnlockLoading() {
        if (mLockDialog != null)
            mLockDialog.showLoading();
    }

    @Override
    public void hideUnlockLoading() {
        if (mLockDialog != null)
            mLockDialog.hideLoading();
    }

    @Override
    public void onTradeRefundFailed() {
        startPrint();
    }


    private void setItemChecked(int groupPosition, int childPosition) {
        ClassifyData.Classify classify = classifyData.getData().get(groupPosition).getChildren().get(childPosition);
        loadDataByClassify(classify);
        if (mClassifyWrapper.getType() == ClassifyWrapper.TYPE_EXPANDABLELISTVIEW) {
            mMenuAdapter.setChildPosition(childPosition);
        }
        activityMainBinding.setSelectMenu(classify.getTypeName());
    }


    private void loadDataByClassify(ClassifyData.Classify classify) {
        if (classify.getId() == productViewModel.getTypeId()) {
            return;
        }
        if (!TextUtils.isEmpty(activityMainBinding.editSearch.getText().toString())) {
            activityMainBinding.editSearch.setText("");
            if (activityMainBinding.editSearch.hasFocus())
                activityMainBinding.editSearch.clearFocus();
        }
        productViewModel.setPage(1);
        productViewModel.setTypeId(classify.getId());
        productViewModel.loadData(getTerNo(), true);
    }

    @Override
    public void showImage(Bitmap bitmap) {
        mPaymentDialog.setQRCode(bitmap);
    }

    @Override
    public void onClearAllData(boolean isFinish) {
        Log.i(TAG, "Clear Shopping cart data success! ");
    }

    @Override
    public void onAddShopCar(ShoppingCarItem item) {
        ToastUtils.showShortToast(String.format(getString(R.string.tip_add_shopping_car_success), item.getTitle()));
    }

    public boolean openSerialPort() {
        boolean openSerialPort = false;
        String serialPath = mAppConfigHelper.getSerialPath();
        int serialPort = 0;
        try {
            serialPort = Integer.parseInt(mAppConfigHelper.getSerialPort());
        } catch (NumberFormatException e) {
            e.printStackTrace();
            ToastUtils.showShortToast("非法的串口波特率值！");
            return openSerialPort;
        }
        File file = new File(serialPath);
        if (!file.exists()) {
            ToastUtils.showShortToast("串口文件不存在！");
            return openSerialPort;
        }
        // 打开串口
        openSerialPort = mSerialPortManager.openSerialPort(file, serialPort);
        return openSerialPort;
    }


    private void showLockDialog() {
        mLockDialog = new LockDialog(MainActivity.this, LockDialog.STATUS_LOCKED) {
            @Override
            public void onUnlocked(String pwd) {
                productViewModel.verficatePwd(getTerNo(), pwd, TODO_ONLY_UNLOCK);

            }
        };
        mLockDialog.show();
    }


    private void startPrint() {
        //开始打印
        if (mPushInfo != null) {
            String printStr = appendPrintStr(mPushInfo);
            Log.d(TAG, "printStr=" + printStr);
            USBPrinterMgr.getInstance().startPrint(printStr);
        }
    }


    private void doWithReceivedCommand(String command) {
        Log.d(TAG, "command=" + command);
        if (TextUtils.isEmpty(command)) {
            Log.e(TAG, "command is null!");
            return;
        }
        if (TextUtils.equals(command, ErrorCode.LIGHT_SCRENN_OFFSET_ERROR) || TextUtils.equals(command, ErrorCode.HARDWARE_COMMUNICATEION_ERROR)) {
            hideOutStackDialog();
            showLockDialog();
            productViewModel.saveMistake(getTerNo(), command);
        }
        //出货成功
        else if (TextUtils.equals(command, ErrorCode.GOODS_OUT_OF_MACHINE_SUCCESS)) {
            //取消超时机制
            if (mSerialPortManager != null)
                mSerialPortManager.cancelTimeOutTask();
            hideOutStackDialog();
            //出货成功
            PaySuccessDialog dialog = new PaySuccessDialog(this);
            dialog.show();
            startPrint();
        }
        //出货失败
        else if (TextUtils.equals(command, ErrorCode.GOODS_OUT_OF_MACHINE_FAILED)) {
            //取消超时机制
            if (mSerialPortManager != null)
                mSerialPortManager.cancelTimeOutTask();
            hideOutStackDialog();
            //退款
            productViewModel.tradeRefund(mTradeNo);
            showOutStackFailedDialog();
        } else if (TextUtils.equals(command, ErrorCode.TEMPERATURE_REPORT)){
            String startCommand = command.substring(0, 4);
            String endCommand = command.substring(8);
            //温度上报
            if (TextUtils.equals(startCommand, "AA00") && TextUtils.equals(endCommand, "C2DD")) {
                String tempStr = command.substring(4, 6);
                String humStr = command.substring(6, 8);
                try {
                    int temp = Integer.parseInt(tempStr, 16);
                    int hum = Integer.parseInt(humStr, 16);
                    productViewModel.putTerEnv(getTerNo(), temp, hum);
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
            }
        }
        else {
            Log.w(TAG, "Invalid Command !");
        }
    }

    private void showOutStackFailedDialog() {
        String phone = (String) GlobalData.getInstance().getData(ARGConstant.ARG_PHONE);
        PayFailedDialog dialog = new PayFailedDialog(this, phone) {
            @Override
            protected void onStopCountDown() {
                showLockDialog();
            }
        };
        dialog.show();
    }

    @Override
    public void onSuccess(File device) {
        Log.i(TAG, "Open serial port success!");

    }

    @Override
    public void onFail(File device, Status status) {
        Log.i(TAG,"Open serial port failed!");
        ToastUtils.showShortToast("打开串口失败！");
    }

    @Override
    protected void onCall(RxEvent event) {
        switch (event.code) {
            case EventCode.PUSH_PAY_SUCCESS:
                mPushInfo = (PushInfo) event.obj;
                Log.e(TAG, "mPushInfo=" + mPushInfo);
                if (mPushInfo.getCode() == ErrorCode.CODE_PUSH_PAY_SUCCESS) {
                    if (mPaymentDialog != null && mPaymentDialog.isShowing()) {
                        mPaymentDialog.dismiss();
                    }
                    //获取支付成功后推送过来的交易的订单号
                    mTradeNo = mPushInfo.getTradeNo();
                    mOutStackDialog = new LoadingDialog(this, getString(R.string.out_of_stock));
                    mOutStackDialog.show();
                    List<PushInfo.DrugInfosBean> drugInfos = mPushInfo.getDrugInfos();
                    //给下位机发送指令
                    sendAppendCmd(drugInfos);
                }
                break;
            case EventCode.MODIFY_STACK_CODE:
                ProductData.Product product = (ProductData.Product) event.obj;
                updateProductStack(product);
                break;
        }
    }

    /**
     * 拼接打印成功的内容
     */
    private String appendPrintStr(PushInfo info) {
        List<PushInfo.DrugInfosBean> drugInfos = info.getDrugInfos();
        StringBuilder sb = new StringBuilder();
        if (drugInfos != null && !drugInfos.isEmpty()) {
            sb.append("交易编号：").append(info.getTradeNo()).append("\n");
            sb.append("机号：").append(getTerNo()).append("\n");
//              sb.append("日期：").append(TimeUtil.getCurrentTime("yyyy年MM月dd日 HH:mm:ss")).append("\n");
            sb.append("---------------------------------\n");
            sb.append("商品名称       数量  金额\n");
            double totalPrice = 0;
            for (int i = 0; i < drugInfos.size(); i++) {
                PushInfo.DrugInfosBean drugInfo = drugInfos.get(i);
                String subStr = subStringByGB2312(drugInfo.getDrugName(), mMaxPrintLength);
                sb.append(subStr).append(drugInfo.getQuantity() + "  ").append(drugInfo.getDrugPrice()).append("\n");
                double prices = drugInfo.getDrugPrice() * drugInfo.getQuantity();
                totalPrice = DoubleMathUtil.add(totalPrice, prices);
            }
            sb.append("合计                 ").append(totalPrice).append("\n");
            sb.append("---------------------------------\n");
            String phone = (String) GlobalData.getInstance().getData(ARGConstant.ARG_PHONE);
            sb.append("售后电话：").append(phone).append("\n");
            sb.append("如遇到落药失败并退款失败，请凭此小票到门店退款或者取药");
        }
        return sb.toString();
    }

    /**
     * 根据字符串截取前指定字节数,按照GBK编码进行截取
     *
     * @param str 原字符串
     * @param len 截取的字节数
     * @return 截取后的字符串
     */
    private static String subStringByGB2312(String str, int len) {
        String result = null;
        if (str != null) {
            try {
                byte[] a = str.getBytes("GB2312");
                if (a.length == len) {
                    result = str;
                } else if (len > a.length) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(str);
                    for (int i = 0; i < (len - a.length); i++) {
                        sb.append("    ");
                    }
                    result = sb.toString();
                } else if (len > 0) {
                    result = new String(a, 0, len, "GB2312");
                    int length = result.length();
                    if (str.charAt(length - 1) != result.charAt(length - 1)) {
                        if (length < 2) {
                            result = null;
                        } else {
                            result = result.substring(0, length - 1) + "...";
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }


    /**
     * 发送拼接的指令
     */
    private void sendAppendCmd(List<PushInfo.DrugInfosBean> drugInfos) {
        if (drugInfos != null && !drugInfos.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < drugInfos.size(); i++) {
                PushInfo.DrugInfosBean drugInfo = drugInfos.get(i);
                int count = drugInfo.getQuantity();
                for (int j = 0; j < count; j++) {
                    if (j == count - 1) {
                        if (i == drugInfos.size() - 1) {
                            sb.append(drugInfo.getCommand())
                                    .append("BE");
                        } else {
                            sb.append(drugInfo.getCommand())
                                    .append("BB");
                        }

                    } else {
                        sb.append(drugInfo.getCommand())
                                .append("BB");
                    }
                }
                updateProductStack(drugInfo);
            }
            Log.d(TAG, "Send Command------>" + sb.toString());
            byte[] command = StringUtils.hexStringToBytes(sb.toString());
            if (mSerialPortManager != null)
                mSerialPortManager.sendBytes(command);
        }
    }

    @Override
    protected void onCountDownFinished() {
        if (mAppConfigHelper != null && mAppConfigHelper.hasData())
            productViewModel.clearShoppingCart();
        dismissDialog();
    }


    private void dismissDialog() {
        if (mConfirmDialog != null && mConfirmDialog.isShowing())
            mConfirmDialog.dismiss();
        if (mPaymentDialog != null && mPaymentDialog.isShowing())
            mPaymentDialog.dismiss();
    }


    /**
     * 更新库存数
     *
     * @param drugInfo 购买的商品对象
     */
    private void updateProductStack(PushInfo.DrugInfosBean drugInfo) {
        for (int i = 0; i < mProductList.size(); i++) {
            ProductData.Product product = mProductList.get(i);
            if (TextUtils.equals(product.getPlanId(), drugInfo.getPlanId())) {
                product.setDrugQuantity(product.getDrugQuantity() - drugInfo.getQuantity());
                notifyItemChanged(i);
                break;
            }
        }
    }

    @Override
    protected boolean isStartCountDown() {
        return true;
    }

    /**
     * 更新库存数
     *
     * @param productInfo 更新的对象
     */
    private void updateProductStack(ProductData.Product productInfo) {
        for (int i = 0; i < mProductList.size(); i++) {
            ProductData.Product product = mProductList.get(i);
            if (TextUtils.equals(product.getPlanId(), productInfo.getPlanId())) {
                product.setDrugQuantity(productInfo.getDrugQuantity());
                notifyItemChanged(i);
                break;
            }
        }
    }


    private void notifyItemChanged(int position){
        if(mClassifyWrapper.getType()==ClassifyWrapper.TYPE_RECYCLERVIEW){
            position++;
        }
        mProductAdapter.notifyItemChanged(position, "updateStack");
    }


    private BroadcastReceiver mNetReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
                ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(
                        Context.CONNECTIVITY_SERVICE);
                NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
                if (networkInfo != null && networkInfo.isAvailable()) {
                    String terNo = getTerNo();
                    if (TextUtils.isEmpty(terNo)) {
                        Log.d(TAG, "Reget TradeNo when has network!");
                        productViewModel.getTerNo();
                    }
                } else {// 无网络
                    Log.e(TAG, "No available network!");
                }
            }
        }
    };

    private void openPullMenu() {
        mMenuIsShow = true;
        activityMainBinding.flayoutPullMenu.setVisibility(View.VISIBLE);
        ValueAnimator animator = createDropAnimator(activityMainBinding.layoutPullMenu, 0,
                400);
        animator.start();

    }

    private void closePullMenu() {
        mMenuIsShow = false;
        activityMainBinding.flayoutPullMenu.setVisibility(View.GONE);
//        int origHeight = activityMainBinding.layoutPullMenu.getHeight();
//        ValueAnimator animator = createDropAnimator(activityMainBinding.layoutPullMenu, origHeight, 0);
//        animator.addListener(new AnimatorListenerAdapter() {
//            public void onAnimationEnd(Animator animation) {
//                // 动画结束时隐藏view
//                activityMainBinding.layoutPullMenu.setVisibility(View.GONE);
//            }
//        });
//        animator.start();
    }

    private ValueAnimator createDropAnimator(final View view, int start, int end) {
        // 创建一个数值发生器
        ValueAnimator animator = ValueAnimator.ofInt(start, end);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                int value = (Integer) valueAnimator.getAnimatedValue();
                ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
                layoutParams.height = value;
                view.setLayoutParams(layoutParams);
            }
        });
        return animator;
    }

    OnClassifyListener mOnClassifyListener = new OnClassifyListener() {
        @Override
        public void onGroupClick(int groupPosition) {
            ClassifyData.Classify classify = classifyData.getData().get(groupPosition);
            if (classify.getId() != productViewModel.getTypeId()) {
                loadDataByClassify(classify);
            }
            if (mClassifyWrapper.getType() == ClassifyWrapper.TYPE_EXPANDABLELISTVIEW) {
                mMenuAdapter.setGroupAndChildPosition(groupPosition, -1);
            } else {
                activityMainBinding.setSelectMenu(classify.getTypeName());
                mPullMenuAdapter.setGroupPosition(groupPosition);
                mSubMenuAdapter.setGroupPosition(groupPosition);
                mSubClassifyList.clear();
                List<ClassifyData.Classify> classifies= classify.getChildren()==null?new ArrayList<>():classify.getChildren();
                mSubClassifyList.addAll(classifies);
                mSubMenuAdapter.notifyDataSetChanged();
            }
        }

        @Override
        public void onChildClick(int groupPosition, int childPosition) {
            setItemChecked(groupPosition, childPosition);
            if (mClassifyWrapper.getType() == ClassifyWrapper.TYPE_RECYCLERVIEW) {
                closePullMenu();
            }

        }
    };

}
